package cc.iotkit.web.task;

import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.constant.Constants;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.service.DeviceInfoDataImpl;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.dto.vo.product.ProductVo;
import cc.iotkit.manager.dto.vo.record.DoorAccessRecordVo;
import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo;
import cc.iotkit.manager.service.AlertService;
import cc.iotkit.manager.service.DoorAccessRecordService;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.manager.service.IProductService;
import cc.iotkit.model.alert.AlertConfig;
import cc.iotkit.model.alert.AlertRecord;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DevicePropertyCache;
import cc.iotkit.model.product.Product;
import cc.iotkit.model.product.ThingModel;
import cc.iotkit.model.report.DoorAccessRecord;
import cc.iotkit.web.controller.WebSocketServer;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import software.amazon.ion.Decimal;

import javax.websocket.Session;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * 数字孪生websocket定时上传数据
 */
@Component
@Slf4j
public class IotTask {
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private IDeviceManagerService deviceServiceImpl;
    @Autowired
    private DeviceInfoDataImpl deviceInfoDataImpl;
    @Autowired
    private IProductService productService;
    @Autowired
    DoorAccessRecordService doorAccessRecordService;
    @Autowired
    private AlertService alertService;
    @Autowired
    @Qualifier("deviceInfoDataCache")
    private IDeviceInfoData deviceInfoData;
    @Scheduled(cron = "0/5 * * * * ?")
    public void socketTask(){
        List<DeviceInfo> deviceInfoList = deviceInfoDataImpl.findByPk(Constants.DOOR_PK);
        for (DeviceInfo deviceInfo:deviceInfoList){
            if (!deviceInfo.isOnline()){
                deviceInfo.setState(new DeviceInfo.State(true, null, null));
                deviceInfoDataImpl.save(deviceInfo);
            }
        }
        deviceInfoList = deviceInfoDataImpl.findByPk(Constants.CAMERA_PK);
        for (DeviceInfo deviceInfo:deviceInfoList){
            if (!deviceInfo.isOnline()){
                deviceInfo.setState(new DeviceInfo.State(true, null, null));
                deviceInfoDataImpl.save(deviceInfo);
            }
        }

        Map<String, Session> sessionMap = webSocketServer.getOnlineSessionClientMap();
        Set<String> keys = sessionMap.keySet();
        for (String key:keys) {
            //根据链接的客户端key 推送不同的内容
            String message = "";
            //判断当前socket客户端，如果是品类，，返回对应品类下搜有设备的在线情况
            if (key.indexOf("categories_show_")>-1){
                String category = key.replace("categories_show_","");
                deviceInfoList = deviceServiceImpl.findByCategory(category);
                if (Constants.BLOWER.equals(category)){
                    DeviceInfo deviceInfo = deviceServiceImpl.getDetail("17189655941600030000000000000005a");
                    if (deviceInfoList == null){
                        deviceInfoList = new ArrayList<>();
                    }
                    deviceInfoList.add(deviceInfo);
                }
                //便利品类下设备封装在线状态
                JSONArray jsonMsg = new JSONArray();
                if (deviceInfoList!=null && deviceInfoList.size()>0) {
                    JSONObject object = null;
                    for (DeviceInfo deviceInfo:deviceInfoList){
                        object = new JSONObject();
                        object.put("deviceNo", deviceInfo.getDeviceId());
                        deviceInfo.getProperty().get("");
                        Map<String, DevicePropertyCache> propertyCacheMap = deviceInfoData.getProperties(deviceInfo.getDeviceId());
                        object.put("status", deviceInfo.getState().isOnline()?"1":"0");
                        if (propertyCacheMap!=null && propertyCacheMap.get("onOff")!=null && "0".equals(propertyCacheMap.get("onOff").getValue())){
                            object.put("status","3");
                        }
                        jsonMsg.add(object);
                    }
                }
                message = jsonMsg.toJSONString();
            }else if (key.indexOf("device_show_")>-1){
                String deviceId = key.replace("device_show_","");
                JSONObject returnObj = new JSONObject();
                DeviceInfo deviceInfo = deviceServiceImpl.getDetail(deviceId);
                //判断当前设备类型 做不同处理 摄像头 只返回基本信息，门禁 需要返回近24小时的出入记录；其他设备返回当前设备的物模型数据
                if (deviceInfo!=null) {
                    ProductVo productVo = productService.getDetail(deviceInfo.getProductKey());
                    returnObj.put("categoryCode",productVo.getCategory());
                    returnObj.put("deviceId",deviceId);
                    JSONArray baseInfo = new JSONArray();
                    JSONObject sonObj = new JSONObject();

                    JSONArray assetInfo = new JSONArray();
                    if (deviceInfo.getManufacturers()!=null) {
                        sonObj.put("name", "生产厂家");
                        sonObj.put("value", deviceInfo.getManufacturers().getName());
                        assetInfo.add(sonObj);
                        sonObj = new JSONObject();
                        sonObj.put("name","联系电话");
                        sonObj.put("value",deviceInfo.getManufacturers().getLinkPhone());
                        assetInfo.add(sonObj);
                    }

                    if (deviceInfo.getSupplier()!=null) {
                        sonObj = new JSONObject();
                        sonObj.put("name", "供货厂家");
                        sonObj.put("value", deviceInfo.getSupplier().getName());
                        assetInfo.add(sonObj);

                        sonObj = new JSONObject();
                        sonObj.put("name", "联系电话");
                        sonObj.put("value", deviceInfo.getSupplier().getLinkPhone());
                        assetInfo.add(sonObj);
                    }

                    sonObj = new JSONObject();
                    sonObj.put("name","购置时间");
                    sonObj.put("value",deviceInfo.getBugTime());
                    assetInfo.add(sonObj);

                    returnObj.put("assetInfo",assetInfo);

                    JSONArray realtime = new JSONArray();

                    if (Constants.CAMERA_PK.equals(deviceInfo.getProductKey())){
                        sonObj = new JSONObject();
                        sonObj.put("deviceId",deviceId);
                        baseInfo.add(sonObj);
                    }else if (Constants.DOOR_PK.equals(deviceInfo.getProductKey())){
                        sonObj = new JSONObject();
                        sonObj.put("name","设备名称");
                        sonObj.put("value",deviceInfo.getDeviceName());
                        baseInfo.add(sonObj);

                        sonObj = new JSONObject();
                        sonObj.put("name","运行状态");
                        sonObj.put("value","在线");
                        baseInfo.add(sonObj);
                        //获取人员出入记录
                        PageRequest<DoorAccessRecord> query = new PageRequest<>();
                        DoorAccessRecord doorAccessRecord = new DoorAccessRecord();
                        doorAccessRecord.setDeviceName(deviceInfo.getDeviceName());
                        query.setData(doorAccessRecord);

                        Map map = new HashMap();
                        map.put("dateTime", "DESC");
                        query.setSortMap(map);
                        Paging<DoorAccessRecordVo> doorAccessRecordVoPaging = doorAccessRecordService.selectPageDoorAccessRecordList(query);
                        if (doorAccessRecordVoPaging.getRows()!=null && doorAccessRecordVoPaging.getRows().size()>0){
                            List<DoorAccessRecordVo> doorAccessRecordVoList = doorAccessRecordVoPaging.getRows();
                            JSONObject renyuan = null;
                            for (DoorAccessRecordVo doorAccessRecordVo:doorAccessRecordVoList){
                                renyuan = new JSONObject();
                                renyuan.put("employeeNo",doorAccessRecordVo.getEmployeeNo());
                                renyuan.put("employeeName",doorAccessRecordVo.getEmployeeName());
                                renyuan.put("dateTime",doorAccessRecordVo.getDateTime());
                                realtime.add(renyuan);
                            }
                        }
                        returnObj.put("realtime",realtime);
                    }else {

                        sonObj = new JSONObject();
                        sonObj.put("name","设备名称");
                        sonObj.put("value",deviceInfo.getDeviceName());
                        baseInfo.add(sonObj);

                        sonObj = new JSONObject();
                        sonObj.put("name","运行状态");
                        sonObj.put("value",deviceInfo.isOnline()?"在线":"离线");
                        baseInfo.add(sonObj);

                        //获取当前产品的物模型，==给当前设备封装物模型值
                        ThingModelVo thingModelVo = productService.getThingModelByProductKey(deviceInfo.getProductKey());
                        List<ThingModel.Property> propertyList = thingModelVo.getModel().getProperties();
                        Map<String, DevicePropertyCache> properties = (Map<String, DevicePropertyCache>) deviceInfo.getProperty();
                        Set<String> keySet = properties.keySet();
                        for (String ke:keySet) {
                            JSONObject realData = null;
                            for (ThingModel.Property property:propertyList) {
                                if (property.getIdentifier().equals(ke)) {
                                        realData = new JSONObject();
                                        realData.put("name", property.getName());
                                        if (properties.get(ke)!=null) {
                                            String value = properties.get(ke).getValue()!=null ? properties.get(ke).getValue()+"":"";
                                            if ("onOff".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开机";
                                                }else {
                                                    value="关机";
                                                }
                                            }else if ("runningMode".equals(property.getIdentifier())){
                                                if ("0".equals(value)){
                                                    value="制冷模式";
                                                }else if("1".equals(value)) {
                                                    value="制热模式";
                                                }else if("2".equals(value)) {
                                                    value="通风模式";
                                                }
                                            }else if ("breakdown".equals(property.getIdentifier())){
                                                if ("0".equals(value)){
                                                    value="无";
                                                }else if("1".equals(value)) {
                                                    value="有";
                                                }
                                            }else if ("lowWindSpeed".equals(property.getIdentifier())){
                                                if ("0".equals(value)){
                                                    value="正常";
                                                }else if("1".equals(value)) {
                                                    value="报警";
                                                }
                                            }else if ("highWindSpeed".equals(property.getIdentifier())){
                                                if ("0".equals(value)){
                                                    value="正常";
                                                }else if("1".equals(value)) {
                                                    value="报警";
                                                }
                                            }else if ("call1Level1".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有一级报警";
                                                }else {
                                                    value="无一级报警";
                                                }
                                            }else if ("call1Level2".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有二级报警";
                                                }else {
                                                    value="无二级报警";
                                                }
                                            }else if ("malfunction1".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有故障";
                                                }else {
                                                    value="无故障";
                                                }
                                            }else if ("call2Level1".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有一级报警";
                                                }else {
                                                    value="无一级报警";
                                                }
                                            }else if ("call2Level2".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有二级报警";
                                                }else {
                                                    value="无二级报警";
                                                }
                                            }else if ("malfunction2".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有故障";
                                                }else {
                                                    value="无故障";
                                                }
                                            }else if ("nfjgz".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="有故障";
                                                }else {
                                                    value="无故障";
                                                }
                                            }else if ("djryqt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("jsqqt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("jzgzzsd".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("cxzt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("zxzt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("sfjbpqgz".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("sfjqf".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("djrygrbh".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("djregrbh".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="报警";
                                                }else {
                                                    value="正常";
                                                }
                                            }else if ("djreqt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("jzyxzsd".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("sfjqt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }else if ("fgdjrqt".equals(property.getIdentifier())){
                                                if ("1".equals(value)){
                                                    value="开启";
                                                }else {
                                                    value="关闭";
                                                }
                                            }

                                            if ("0.0".equals(value+"")){
                                                value = "0";
                                            }

                                            realData.put("value", value);
                                        }else {
                                            realData.put("value", "");
                                        }
                                        realData.put("unit", property.getUnit());
                                    break;
                                }
                            }
                            if (realData!=null) {
                                realtime.add(realData);
                            }
                        }
                        returnObj.put("realtime",realtime);
                    }
                    returnObj.put("baseInfo",baseInfo);
                }
                message = returnObj.toJSONString();
            }
            webSocketServer.sendToOne(key,message);
        }
        log.info("定时任务执行{}",new Date());
    }

    /**
     * 每天晚上获取需要到保养周期的设备列表，产生保养提醒数据
     */
    @Scheduled(cron = "0 0 23 * * ?")
    public void maintainDeviceTask(){
        //根据下次保养日期、累计运行时长 获取当前需保养的设备列表，并增加到报警列表中
        List<DeviceInfo> maintainDeviceList = deviceServiceImpl.selectMaintainDeviceList();
        if (maintainDeviceList!=null && maintainDeviceList.size()>0) {
            AlertConfig alertConfig = null;
            for (DeviceInfo deviceInfo : maintainDeviceList) {
                alertConfig = new AlertConfig();
                alertConfig.setLevel("1");
                alertConfig.setName("设备保养提醒");
                String content = "【" + deviceInfo.getDeviceName() + "】已到保养周期，请尽快安排保养。";
                AlertRecord record = new AlertRecord();
                record.setLevel("1");
                record.setName("设备保养提醒");
                record.setAlarmType("5");
                record.setDeviceId(deviceInfo.getDeviceId());
                record.setDeviceName(deviceInfo.getDeviceName());
                record.setAlarmTypeName("保养提醒");
                record.setFloor(deviceInfo.getFloor());
                record.setDetails(content);
                alertService.addAlert(record);
            }
        }
    }


    /**
     * 每天晚上获取需要到保养周期的设备列表，产生保养提醒数据
     */
    @Scheduled(cron = "0 23 * * * ?")
    public void needMaintainTimeDeviceList(){
        List<Product> products = productService.selectAll();
        for (Product product:products) {
            if (product != null && product.getNeedMaintainTime() != null && product.getNeedMaintainTime().compareTo(Decimal.ZERO)>0) {
                //累计运行时长 获取当前需保养的设备列表，并增加到报警列表中
                List<DeviceInfo> maintainDeviceList = deviceServiceImpl.selectRunningToolongDeviceList(product);
                if (maintainDeviceList!=null&& maintainDeviceList.size()>0) {
                    AlertConfig alertConfig = null;
                    for (DeviceInfo deviceInfo : maintainDeviceList) {
                        alertConfig = new AlertConfig();
                        alertConfig.setLevel("1");
                        alertConfig.setName("设备保养提醒");
                        String content = "【" + deviceInfo.getDeviceName() + "】已累计运行"+deviceInfo.getRunningHours()+"小时，请尽快安排保养。";
                        AlertRecord record = new AlertRecord();
                        record.setLevel("1");
                        record.setName("设备保养提醒");
                        record.setAlarmType("5");
                        record.setDeviceId(deviceInfo.getDeviceId());
                        record.setDeviceName(deviceInfo.getDeviceName());
                        record.setAlarmTypeName("保养提醒");
                        record.setFloor(deviceInfo.getFloor());
                        record.setDetails(content);
                        alertService.addAlert(record);
                    }
                }
            }
        }
    }

    /**
     * 每天定时累计设备运行时长
     */
    @Scheduled(cron = "30 23 * * * ?")
    public void updateDeviceRunningTime(){
        List<Product> products = productService.selectAll();
        for (Product product:products) {
            if (product != null && product.getNeedMaintainTime() != null && product.getNeedMaintainTime().compareTo(Decimal.ZERO)>0) {
                //批量处理累计运行时长
                List<DeviceInfo> maintainDeviceList = deviceServiceImpl.findByPk(product.getProductKey());
                if (maintainDeviceList!=null&& maintainDeviceList.size()>0) {
                    for (DeviceInfo deviceInfo:maintainDeviceList){
                        long runningtime = 0;
                        if (deviceInfo != null) {
                            runningtime = deviceInfo.getRunningHours();
                        }
                        runningtime+=24;
                        deviceInfo.setRunningHours(runningtime);
                        deviceInfoDataImpl.save(deviceInfo);
                    }
                }
            }
        }
    }
}
